<?php

namespace app\db\model;

use think\Db;
use think\Model;
use think\Cache;
class DbData extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $dbName     = 'db_data';

    # --------------------------------- 查询类接口 START------------------------------------
    /**
     * 获取模板信息
     * @param int  $data_id 模块ID
     * @author MSQ 2021-8-6
    **/
    public function getDetails($data_id = 0,$field = '*')
    {
        $where = [
            'id'     => $data_id,
            'status' => 1,
        ];
        if ($field && $field != '*' && count(explode(',', $field)) == 1) {
            // 只取一个字段
            $info = $this->where($where)->value($field);
        }else{
            $info = db($this->dbName)->field($field)->where($where)->find();
        }
        
        return $info;
    }
    /**
     * 根据变量获取回答
     * @param int  $data_id 模块ID
     * @author MSQ 2021-8-6
    **/
    public function getDataByQuestionId($database_id = 0,$question_ids = 0,$field = '*',$isCheckEmpty = false)
    {
        if (!$database_id || !$question_ids) return false;
        $where = [
            'database_id' => $database_id,
            'status'      => 1,
        ];
        # 过滤空回答
        if ($isCheckEmpty) $where['answer_value'] = ['NEQ',''];

        if (is_array($question_ids)) {
            $where['question_id'] = ['IN',$question_ids];
            if ($field && $field != '*' && count(explode(',', $field)) == 1) {
                // 只取一个字段
                $info = $this->where($where)->column($field);
            }else{
                $info = db($this->dbName)->field($field)->where($where)->select();
            }
        }else{
            $where['question_id'] = $question_ids;
            # value/find 多用于判断变量是否有回答 无法查出某一变量下所有回答
            if ($field && $field != '*' && count(explode(',', $field)) == 1) {
                // 只取一个字段 
                $info = $this->where($where)->value($field);
            }else{
                $info = db($this->dbName)->field($field)->where($where)->find();
            }
        }
        return $info;
    }
    /**
     * 根据itemRelationData获取回答
     * @param int  $data_id 模块ID
     * @author MSQ 2021-8-6
    **/
    public function getListsByItemRelationDataId($itemRelationDataIds = 0,$field = '',$order = 'id ASC')
    {
        if (!$itemRelationDataIds) return false;
        $where = [
            'status' => 1,
        ];
        $where['item_relation_data_id'] = $itemRelationDataIds;

        if (!$field) $field = 'id,item_relation_data_id,question_id,answer_value,other_data_value';
        if (is_array($itemRelationDataIds)) {
            $where['item_relation_data_id'] = ['IN',$itemRelationDataIds];
        }
        $info = db($this->dbName)->where($where)->field($field)->order($order)->select();
        return $info;


    }
    # ---------------------------------- 查询类接口 END-------------------------------------
    
    # ------------------------------- 数据处理类接口 START ----------------------------------
    /**
     * 创建用户时同步添加基础模块关联及回答
     * @param int  $data 相关数据
     * @author MSQ 2021-8-6
    **/
    public function createUserSyncBasicItemData($data = [])
    {
        $template_id  = $data['template_id'];
        $user_id      = $data['user_id'];
        $master_db_id = $data['master_db_id'];// 总库ID
        if (!$template_id || !$user_id || !$master_db_id) return false;

        # 添加基础模块itemRelationData
        $basicItemId = model('DbItem')->getBasicItemInfo('id');
        $itemRelationDataId = model('DbItemRelationData')->createItemRelationData($user_id,$basicItemId);
       
        if (!$itemRelationDataId) return false;

        $userNumberKey = model('DbItem')->getUserNumberKey();
        $q_keys = [$userNumberKey];

        $basicItemKey = model('DbItem')->getBasicItemKey();
        foreach ($data as $k_qkey=>$v_value){
            $q_keys[] = $basicItemKey.'__'.$k_qkey;
        }

        # 需要同步的变量信息
        $questionInfo = model('DbQuestion')->getQuestionListByQuestionKey($q_keys,'id,question_key,question_type');
        if (!$questionInfo) return true;

        $addData = [];
        foreach ($questionInfo as $k_q => $v_qval){
            $qkey = substr($v_qval['question_key'],strlen($basicItemKey.'__'));
            $value = '';
            if ($qkey == 'user_sex'){
                $sexOption = model('DbTemplateRelationQuestionOption')->getOptionListByQId($template_id,$v_qval['id']);
                $sexOption = array_column($sexOption,NULL,'option_key');
                if ($data[$qkey] == 1) {
                    $value = $sexOption['man']['option_id'];
                }elseif ($data[$qkey] == 2) {
                    $value = $sexOption['woman']['option_id'];
                }
            }else{
                $value = $data[$qkey];
            }
            $addData[$k_q]['item_relation_data_id'] = $itemRelationDataId;
            $addData[$k_q]['database_id']  = $master_db_id;
            $addData[$k_q]['user_id']      = $user_id;
            $addData[$k_q]['question_id']  = $v_qval['id'];
            $addData[$k_q]['answer_value'] = $value;
            $addData[$k_q]['value']        = model('DbQuestion')->checkQuestionIsNeedValue($v_qval['question_type'],$v_qval['id'],$value);# 是否需要value 单选 多选 下拉时需要
        }

        if (!$addData) return true;

        $addDataRes = $this->setAttr('id',null)->isUpdate(false)->saveAll($addData);

        if (!$addDataRes) return false;
        
        return true;
    }
    /**
     * 删除回答
     * @param int  $database_id 数据库id
     * @param int  $delUserIds 删除的用户id
     * @author MSQ 2021-8-7
    **/
    public function deleteDbData($where = [])
    {
        if (!$where) return true;
        $where['status'] = 1;
        return $this->update(['status' => 0],$where);
    }
    /**
     * 保存数据
     * @param int  $database_id 总库id
     * @param int  $user_id 保存的用户
     * @author MSQ 2021-8-17
    **/
    public function saveDatabaseAnswer($usercare_id = 0,$database_id = 0,$user_id = 0,$item_data = [])
    {
        if (!$database_id || !$item_data || !$user_id) return false;
        $operater_name = model('DbUsercare')->getDetails($usercare_id,'name');

        $item_data = array_column($item_data,NULL,'item_id');

        # 同步用户信息 ========================================================
        $saveUserInfo = [];
        $basicItemId = model('DbItem')->getBasicItemInfo('id');
        if (isset($item_data[$basicItemId])) {
            $basicQuestion = model('DbQuestion')->getBasicInfo();
            $basicQuestion = array_column($basicQuestion,NULL,'id');
            $questionData  = $item_data[$basicItemId]['item_data'][0]['questionData'];
            foreach ($questionData as $key => $value) {
                if (isset($basicQuestion[$value['question_id']])) {
                    $question_key = $basicQuestion[$value['question_id']]['question_key'];
                    $saveUserInfo[$question_key] = @$value['answer_value'][0];
                }
            }
        }
        $saveUser = model('DbUser')->updataInfoBySaveDatabaseData($user_id,$saveUserInfo);
        if (!$saveUser) return false;      
        # 同步用户信息 END ========================================================

        $itemRelationDataModel = model('DbItemRelationData');
        $dbQuestionModel = model('DbQuestion');
        //初始化item_relation排序
        $sortItemRelationData = [];
        foreach ($item_data as $key => $value) {
            $item_id = $value['item_id'];
            if (!@$value['item_data']) $value['item_data'] = [];

            foreach ($value['item_data'] as $k_i => $v_i) {                
                $itemRelationId = @$v_i['itemRelationId'];//当前的item_relation_id，为空则说是新增的item_relation
                $questionData   = @array_column($v_i['questionData'],NULL,'question_id');//回答的数据
                if (!$questionData) continue;
                # 没有关联模块 创建
                if (!$itemRelationId) $itemRelationId = $itemRelationDataModel->createItemRelationData($user_id,$key);
                if (!$itemRelationId) return false;

                $whereQuestionInfo = [
                    'item_id' => $item_id,
                    'id'      => ['IN',array_keys($questionData)],
                ];
                $allQuestion = model('DbQuestion')->customQuery($whereQuestionInfo);
                $allQuestion = array_column($allQuestion,NULL,'id');

                foreach ($questionData as $question_id => $v_qd_as) {
                    $questionInfo = @$allQuestion[$question_id];
                    if (!$questionInfo) continue;

                    # 获取原有的database_data_id，有值则说明以前存在数据 属编辑 否则说明是新填写的数据
                    $db_data_id = isset($v_qd_as['db_data_id']) ? $v_qd_as['db_data_id'] : [];
                    
                    //如果id为空，则获取缓存，如果缓存有，则说明数据已插入，而又因某种原因（比如：nginx返回数据丢失，前端js设置id错误等）造成id丢失
                    $redis_key = 'db_da_id_'.$database_id.'_'.$user_id.'_'.$itemRelationId.'_'.$questionInfo['id'];
                    if (empty($db_data_id)) {
                        $db_data_id = Cache::get($redis_key);
                        if (!$db_data_id) $db_data_id = [];
                    }
                    $operaterType = 1;//录入
                    if ($db_data_id) $operaterType = 2;// 修改

                    # 答案
                    $answer_value = $v_qd_as['answer_value'] ? $v_qd_as['answer_value'] : [];

                    # 是否需要添加操作记录
                    $is_save = false;
                    # 答案有值 或 答案为空 原本存在答案（即把答案置空） 或者 答案为空，原本也没有答案，但是空也是答案
                    if ($answer_value || $db_data_id) {
                        $newDataId = [];
                        $use_i     = 0;
                        foreach ($answer_value as $k => $v) {
                            # 循环答案 单选多选下拉框answer_value为选项id 其他为输入框内容
                            # 多选可有多个回答，其他类型仅有一个
                            # 如果答案为‘其他’选项，则传值会把其他填写的内容按'&=>'拼接到选择的选项id后面
                            $temp = explode('&=>',$v);

                            $answerValueData = $temp[0]; // 选项id或输入框的值
                            $valueData = model('DbQuestion')->checkQuestionIsNeedValue($questionInfo['question_type'],$questionInfo['id'],$answerValueData);# value值 有选项的值为answer_value 其他为0
                            $otherDataValue = '';
                            if (in_array($questionInfo['question_type'],[1,2]) && @$temp[1]) {
                                # 单选/多选的‘其他’选项对应回答值
                                $otherDataValue = $temp[1];
                            }
                            if (isset($db_data_id[$use_i]) && !empty($db_data_id[$use_i])) {
                                $saveData = [
                                    'answer_value'     => $answerValueData,
                                    'value'            => $valueData,
                                    'other_data_value' => $otherDataValue,
                                ];
                                # 修改答案
                                $save = $this->update($saveData,['id' => $db_data_id[$use_i]]);
                                if ($save === false) return false;//修改数据失败
                                $is_save     = true;//是修改操作
                                $newDataId[] = $db_data_id[$use_i];//记录操作完的db_data_id
                            }else{
                                # 新增记录
                                $addData = [
                                    'database_id'           => $database_id,
                                    'user_id'               => $user_id,
                                    'item_relation_data_id' => $itemRelationId,
                                    'question_id'           => $questionInfo['id'],
                                    'answer_value'          => $answerValueData,
                                    'value'                 => $valueData,
                                    'other_data_value'      => $otherDataValue,//其他选项对应回答值
                                ];
                                $this->setAttr('id',null)->isUpdate(false)->save($addData);
                                $add_data_id = @$this->id;
                                if (!$add_data_id) return false;//新增回答数据失败
                                $newDataId[] = $add_data_id;//记录操作完的db_data_id
                            }
                            # 使用一个原有ID
                            $use_i++;
                        }
                        # 删除之前存在此次更改后未选择的数据
                        $surplusDataIds = array_slice($db_data_id,$use_i);
                        if ($surplusDataIds) {
                            $this->update(['status' => 0],['id' => ['IN',$surplusDataIds]]);
                            $is_save = true;
                        }
                    }
                    if ($is_save) {
                        # 添加操作记录
                        $operaterData = [
                            'database_id'           => $database_id,
                            'user_id'               => $user_id,
                            'item_relation_data_id' => $itemRelationId,
                            'item_id'               => $item_id,
                            'question_id'           => $questionInfo['id'],
                            'operater_type'         => $operaterType,//1录入2修改
                            'usercare_id'           => $usercare_id,
                            'operater_name'         => $operater_name,//操作的医务名称
                            'details'               => serialize($answer_value),//操作明细
                        ];
                        model('DbOperationRecord')->addData($operaterData);//添加数据库操作记录
                    }
                    $db_data_id = ($db_data_id === false || empty($db_data_id)) ? '' : $db_data_id;

                    # 设置缓存
                    Cache::set($redis_key,$db_data_id,3600);//时效1小时
                }
                # 记录itemRelationData排序
                $sortItemRelationData[$item_id][] = $itemRelationId;
            }
        }
        # 更新itemRelationData排序
        model('DbItemRelationData')->sortItemRelationData($sortItemRelationData);
        return true;
    }
    # --------------------------------- 数据处理类接口 END ----------------------------------
}
